package com.common.ui.fragment;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.common.bean.InfoResult;
import com.common.bean.MsgBean;
import com.common.ui.barlibrary.ImmersionBar;
import com.common.ui.barlibrary.SimpleImmersionOwner;
import com.common.ui.barlibrary.SimpleImmersionProxy;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public abstract class BaseFragment extends Fragment implements SimpleImmersionOwner {

    private EventBus eventBus;
    private Toast toast = null;
    /**
     * 解决getActivity()空指针
     * 可能你遇到过getActivity()返回null，或者平时运行完好的代码，在“内存重启”之后，调用getActivity()的地方却返回null，报了空指针异常。
     * 大多数情况下的原因：你在调用了getActivity()时，当前的Fragment已经onDetach()了宿主Activity。
     * 比如：你在pop了Fragment之后，该Fragment的异步任务仍然在执行，并且在执行完成后调用了getActivity()方法，这样就会空指针。
     * 解决办法：
     * 更"安全"的方法：(对于Fragment已经onDetach这种情况，我们应该避免在这之后再去调用宿主Activity对象，比如取消这些异步任务，
     * 但我们的团队可能会有粗心大意的情况，所以下面给出的这个方案会保证安全)
     * 在Fragment基类里设置一个Activity mActivity的全局变量，在onAttach(Activity activity)里赋值，
     * 使用mActivity代替getActivity()，保证Fragment即使在onDetach后，仍持有Activity的引用
     * （有引起内存泄露的风险，但是异步任务没停止的情况下，本身就可能已内存泄漏，相比Crash，这种做法“安全”些）
     *
     */
    protected Activity activity;
    /**
     * ImmersionBar代理类
     */
    private SimpleImmersionProxy mSimpleImmersionProxy = new SimpleImmersionProxy(this);

    /**
     * 视图是否已经初初始化
     */
    private View view;

    //setUserVisibleHint()在Fragment创建时会先被调用一次，传入isVisibleToUser = false
    //如果当前Fragment可见，那么setUserVisibleHint()会再次被调用一次，传入isVisibleToUser = true
    //如果Fragment从可见->不可见，那么setUserVisibleHint()也会被调用，传入isVisibleToUser = false
    //总结：setUserVisibleHint()除了Fragment的可见状态发生变化时会被回调外，在new Fragment()时也会被回调
    //如果我们需要在 Fragment 可见与不可见时干点事，用这个的话就会有多余的回调了，那么就需要重新封装一个
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        mSimpleImmersionProxy.setUserVisibleHint(isVisibleToUser);
    }

    /**
     * fragment已经关联到activity,这个时候 activity已经传进来了
     * @param context
     */
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        activity = (Activity) context;
    }

    /**
     * 系统创建fragment的时候回调它，在它里面实例化一些变量
     这些个变量主要是:当你 暂停 停止的时候 你想保持的数据
     如果我们要为fragment启动一个后台线程，可以考虑将代码放于此处
     参数:Bundle savedInstance, 用于保存 Fragment 参数,
     Fragement 也可以 重写 onSaveInstanceState(BundleoutState) 方法, 保存Fragement状态
     * @param savedInstanceState
     */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    /**
     * 第一次使用的时候 fragment会在这上面画一个layout出来,为了可以画控件 要返回一个 布局的view
     * 当系统用到fragment的时候 fragment就要返回他的view,越快越好,所以尽量在这里不要做耗时操作
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(getLayoutResId(), container, false);
        bind(view);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mSimpleImmersionProxy.onActivityCreated(savedInstanceState);
        eventBus = EventBus.getDefault();
        eventBus.register(this);
        init();
        loadData();
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    /**
     * 视图销毁的时候讲Fragment是否初始化的状态变为false
     */
    @Override
    public void onDestroyView() {
        if(view!=null){
            ((ViewGroup)view.getParent()).removeView(view);
        }

        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (eventBus != null) {
            eventBus.unregister(this);
        }
        mSimpleImmersionProxy.onDestroy();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        mSimpleImmersionProxy.onHiddenChanged(hidden);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mSimpleImmersionProxy.onConfigurationChanged(newConfig);
    }

    @Override
    public void initImmersionBar() {
        if (isImmersionBarEnabled()) {
            //在BaseActivity里初始化
            ImmersionBar.with(this).init();
        }
    }

    @Override
    public boolean immersionBarEnabled() {
        return isImmersionBarEnabled();
    }

    public abstract boolean isImmersionBarEnabled();

    /**
     * 返回当前fragment布局文件的id
     *
     * @return
     */
    public abstract int getLayoutResId();

    /**
     * 初始化
     */
    public abstract void init();

    /**
     * 加载网络数据
     */
    public abstract void loadData();

    /**
     * 网络数据返回成功
     */
    protected abstract void onSuccess(int what, InfoResult t);

    /**
     * 网络数据返回失败
     */
    protected abstract void onFail(int what, InfoResult t);

    public EventBus getEventBus() {
        return eventBus;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void handlerMeg(MsgBean msgBean){

    }

    public void showToast(String msg) {
        if (toast == null) {
            toast = Toast.makeText(getActivity().getApplicationContext(), msg, Toast.LENGTH_SHORT);
        } else {
            toast.setText(msg);
        }
        toast.show();
    }

    /**
     * 跳转到某个Activity
     *
     * @param activity
     * @param targetActivity
     */
    public void switchTo(Activity activity, Class<? extends Activity> targetActivity, boolean finish) {
        switchTo(activity, new Intent(activity, targetActivity),finish);
    }

    public void switchTo(Activity activity, Intent intent, boolean finish) {
        activity.startActivity(intent);
        if(finish){
            getActivity().finish();
        }
        //overridePendingTransition(R.anim.alpha_out, R.anim.alpha_in);
    }

    public void bind(View view){

    }
}
